﻿namespace DreamBuilder.Common.ServiceProxyFactory
{
    using System;
    using System.Runtime.Remoting.Messaging;
    using System.Runtime.Remoting.Proxies;
    using System.ServiceModel;

    public class ServiceRealProxy<T> : RealProxy
    {
        private string _endpointName;

        public ServiceRealProxy(string endpointName) : base(typeof(T))
        {
            if (string.IsNullOrEmpty(endpointName))
            {
                throw new ArgumentNullException("endpointName");
            }
            this._endpointName = endpointName;
        }

        public override IMessage Invoke(IMessage msg)
        {
            T local = ChannelFactoryCreator.Create<T>(this._endpointName).CreateChannel();
            IMethodCallMessage mcm = (IMethodCallMessage) msg;
            IMethodReturnMessage message2 = null;
            object[] array = Array.CreateInstance(typeof(object), mcm.Args.Length) as object[];
            mcm.Args.CopyTo(array, 0);
            try
            {
                message2 = new ReturnMessage(mcm.MethodBase.Invoke(local, array), array, array.Length, mcm.LogicalCallContext, mcm);
                (local as ICommunicationObject).Close();
            }
            catch (CommunicationException exception)
            {
                (local as ICommunicationObject).Abort();
                message2 = new ReturnMessage(exception, mcm);
            }
            catch (TimeoutException exception2)
            {
                (local as ICommunicationObject).Abort();
                message2 = new ReturnMessage(exception2, mcm);
            }
            catch (Exception exception3)
            {
                if ((exception3.InnerException is CommunicationException) || (exception3.InnerException is TimeoutException))
                {
                    (local as ICommunicationObject).Abort();
                }
                if (exception3.InnerException != null)
                {
                    return new ReturnMessage(exception3.InnerException, mcm);
                }
                message2 = new ReturnMessage(exception3, mcm);
            }
            return message2;
        }
    }
}

